<script lang="ts" setup name="edit">
import type { UploadUserFile } from 'element-plus'
import { Close, Plus } from '@element-plus/icons-vue'
import { ElNotification } from 'element-plus'
import moment from 'moment'
import { PDFDocument } from 'pdf-lib' // 导入 pdf-lib
import { ref } from 'vue'
import { useRouter } from 'vue-router'

defineOptions({
  name: 'Edit',
})
definePageMeta({
  name: 'edit',
  title: '输出页面', // 自定义元信息
  requiresAuth: false, // 其他自定义元信息
  layout: 'default', // 指定布局
  keepalive: true,
}) // 导入 useRouter

const router = useRouter() // 创建 router 实例

// 定义文件对象的类型
interface FileNote {
  name: string // 文件名
  notes: string // 备注
}

const uploadRef = ref<UploadUserFile[]>([])
const fileList = ref<FileNote[]>([]) // 存储选择的文件，使用 FileNote 类型

function remove(index: number) {
  // 从 uploadRef 中移除文件
  uploadRef.value = uploadRef.value.filter((_, i) => i !== index)

  // 从 fileList 中移除对应的文件
  fileList.value = fileList.value.filter((_, i) => i !== index)
}

function handleFileChange(_file: File, _file_List: File[]) {
  fileList.value.push({ name: _file.name, notes: '' })
}

function read_file(file: File) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (event) => {
      if (event.target?.result instanceof ArrayBuffer) {
        resolve(event.target.result)
        // 在这里可以进一步处理ArrayBuffer
      }
      else {
        reject('Failed to read file as ArrayBuffer')
      }
    }
    reader.onerror = (error) => {
      reject(error)
    }
    reader.readAsArrayBuffer(file)
  })
}

async function cp_pdf() {
  const mergedPdf = await PDFDocument.create() // 创建新的 PDF 文档

  for (let index = 0; index < uploadRef.value.length; index++) {
    const file = uploadRef.value[index].raw
    if (!file) {
      throw new Error('文件未找到') // 或者处理错误的逻辑
    }
    const existingPdfBytes = await read_file(file)
    if (existingPdfBytes instanceof ArrayBuffer) {
      try {
        const existingPdf = await PDFDocument.load(existingPdfBytes) // 加载现有的 PDF 文档
        const pageCount = existingPdf.getPageCount()
        const pages = parsePageRange(fileList.value[index].notes) // 解析用户输入的页面范围
        const pageNumbers = pages.filter(num => num < pageCount)
        // console.log(pages, pageNumbers, pageCount)
        const copiedPages = await mergedPdf.copyPages(existingPdf, pageNumbers)
        for (const page of copiedPages) {
          // console.log('page', page)
          mergedPdf.addPage(page) // 将复制的页面添加到新文档
        }
      }
      catch (error) {
        console.error(error)
        ElNotification({
          title: '错误',
          duration: 0,
          message: `受保护的PDF文件 ${file.name} 无法处理。`,
          type: 'error',
        })
      }
    }
    else {
      console.error('读取文件时出错，文件类型不正确')
    }
  }

  const pdfBytes = await mergedPdf.save() // 保存合并后的 PDF
  const blob = new Blob([pdfBytes], { type: 'application/pdf' })
  const url = URL.createObjectURL(blob)
  const now = moment()
  const formattedDate = now.format('HH:mm:ss')
  router.push({
    path: '/view',
    query: { title: `编辑PDF${formattedDate}`, url },
  }) // 跳转到 view.vue，并传递 pdfUrl
  // window.open(url); // 在新窗口中打开合并后的 PDF
}
// 解析页面范围的函数
function parsePageRange(input: string): number[] {
  const output = input
    .replace(/[\uFF00-\uFFFF]/g, (char) => {
      // 将全角字符替换为半角字符
      return String.fromCharCode(char.charCodeAt(0) - 0xFEE0)
    })
    .replace(/,/g, ',') // 替
  const pages: number[] = []
  const ranges = output.split(',') // 按逗号分割输入

  ranges.forEach((range) => {
    const [start, end] = range.split('-').map(Number) // 分割范围
    if (end) {
      for (let i = start; i <= end; i++) {
        pages.push(i - 1) // 添加范围内的所有页面
      }
    }
    else {
      pages.push(start - 1) // 仅添加单个页面
    }
  })

  return pages
}
</script>

<template>
  <div class="cards">
    <div class="cards-content">
      <el-upload
        v-model:file-list="uploadRef"
        class="upload-demo"
        action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
        :auto-upload="false"
        :on-change="handleFileChange"
        :multiple="true"
        :drag="true"
        :show-file-list="false"
        accept=".pdf"
      >
        <template #trigger>
          <el-button :icon="Plus" type="primary">
            选择PDF文件
          </el-button>
        </template>
      </el-upload>

      <table class="file-table">
        <thead>
          <tr>
            <th style="width: 60%">
              文件
            </th>
            <th>输出页面:例如1,3,5-17</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(file, index) in fileList" :key="index">
            <td>
              {{ file.name }}
              <el-button
                type="warning"
                text
                :icon="Close"
                @click="remove(index)"
              />
            </td>
            <td>
              <el-input
                v-model="file.notes"
                placeholder="请输入页面范围:例如1,3,5-17"
              />
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <div class="cards-bottom text-center">
      <el-button type="primary" @click="cp_pdf">
        按以上方式处理PDF文件
      </el-button>
    </div>
  </div>
</template>

<style scoped>
.cards {
  position: relative;
  display: block;
  margin: 20px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
}

.cards-content {
  padding: 20px;
  overflow: auto;
  height: calc(100vh - 300px);
  min-height: calc(100vh - 300px);
  max-height: calc(100vh - 300px);
}

.file-table {
  width: 100%;
  /* 使表格占满可用宽度 */
  border-collapse: collapse;
  /* 合并边框 */
}

.file-table th,
.file-table td {
  border: 1px solid var(--el-border-color);
  /* 添加边框 */
  padding: 10px;
  /* 添加内边距 */
  text-align: left;
  /* 左对齐文本 */
}

.cards-bottom {
  padding-top: 10px;
  height: 50px;
  border-top: 1px solid var(--el-border-color);
}
</style>
